package com.definity.toolkit.ui.animate;

import java.awt.Dimension;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JComponent;

public class Animate {

	public static void animate(AnimateType type, AnimateSpeed speed, JComponent c) {
		if (type.isShow() || type.isHide())
			showOrHide(type, speed, c);
		else if (type.isExpand() || type.isCollapse())
			expandOrCollapse(type, speed, c);
	}

	private static void showOrHide(final AnimateType type, AnimateSpeed speed, final JComponent c) {
		final Dimension originalSize = c.getPreferredSize();

		final Dimension size = new Dimension(originalSize);

		int quocient = 10 * (type.isShow() ? 1 : -1);
		final int part;

		TimerTask task = null;

		if (type.isVertical()) {
			part = originalSize.height / quocient;
			if (type.isShow())
				size.height = 0;

			task = new TimerTask() {
				@Override
				public void run() {
					size.height += part;
					c.setPreferredSize(size);

					c.revalidate();

					if ((type.isShow() && size.height >= originalSize.height)
							|| (type.isHide() && size.height <= 0)) {
						if (type.isHide())
							c.setVisible(false);
						c.setPreferredSize(originalSize);
						cancel();
					}
				}
			};
		} else if (type.isHorizontal()) {
			part = originalSize.width / quocient;
			if (type.isShow())
				size.width = 0;

			task = new TimerTask() {
				@Override
				public void run() {
					size.width += part;
					c.setPreferredSize(size);

					if ((type.isShow() && type.isShow() && size.width >= originalSize.width)
							|| (type.isHide() && size.width <= 0)) {
						if (type.isHide())
							c.setVisible(false);
						c.setPreferredSize(originalSize);
						cancel();
					}
				}
			};
		}

		c.setPreferredSize(new Dimension(size.width, size.height));
		c.setVisible(true);

		Timer t = new Timer();
		t.schedule(task, speed.getTime(), speed.getTime());
	}

	private static void expandOrCollapse(final AnimateType type, AnimateSpeed speed, final JComponent c) {
		Dimension minimumSize = c.getMinimumSize();
		Dimension maximumSize = c.getMaximumSize();
		
		final Dimension size = new Dimension(c.getPreferredSize());
		
		final Dimension toSize = new Dimension(type.isExpand() ? maximumSize : minimumSize);
		
		int quocient = 10 * (type.isExpand() ? 1 : -1);
		final int part;

		TimerTask task = null;

		if (type.isVertical()) {
			part = maximumSize.height / quocient;
			
			task = new TimerTask() {
				@Override
				public void run() {
					size.height += part;
					c.setPreferredSize(size);
					
					c.revalidate();

					if ((type.isExpand() && size.height >= toSize.height) 
							|| (type.isCollapse() && size.height <= toSize.height)) {
						c.setPreferredSize(toSize);
						cancel();
					}
				}
			};
		} else if (type.isHorizontal()) {
			part = maximumSize.width / quocient;
			
			task = new TimerTask() {
				@Override
				public void run() {
					size.width += part;
					c.setPreferredSize(size);

					if (size.width >= toSize.width) {
						c.setPreferredSize(toSize);
						cancel();
					}
				}
			};
		}
		
		c.setPreferredSize(new Dimension(size.width, size.height));
		c.setVisible(true);

		Timer t = new Timer();
		t.schedule(task, speed.getTime(), speed.getTime());
	}
	
}
